# coding:utf-8
"""
请求禅道相关方法
"""
import re, traceback

import requests
from config import ZenTaoConfig, BaseConfig
from password import ZenTaoPass
from app.modules.common.utils import recursive_json_loads
from app.extensions import log


class ZenTao:
    _sessionName = ""
    _sessionID = ""

    def __init__(self):
        if ZenTaoConfig.IS_USE_ZENTAO:
            self._doZenTaoLogin()
        pass

    """
    登陆禅道系统
    """

    def _doZenTaoLogin(self):
        _session = self._doPost(ZenTaoConfig.ZENTAO_GETSESSION_URL)
        self._sessionID = _session.data.sessionID
        self._sessionName = _session.data.sessionName
        self._doPost('%s&account=%s&password=%s' % (
            ZenTaoConfig.ZENTAO_USER_LOGIN_URL, ZenTaoPass.ZENTAO_USERNAME, ZenTaoPass.ZENTAO_PASSWORD))

    def _getUrl(self, url):
        _url = "%s%s" % (ZenTaoPass.ZENTAO_URL, url)
        if ZenTaoConfig.ZENTAO_GETSESSION_URL == url:
            pass
        else:
            if "?" in url:
                _url = "%s&%s=%s" % (_url, self._sessionName, self._sessionID)
            else:
                _url = "%s?%s=%s" % (_url, self._sessionName, self._sessionID)
        return _url

    def _doPost(self, url, data = None, files = None):
        _url = self._getUrl(url)
        if 'f=login' not in _url:
            log.info("_url=%s" % _url)
        _obj = recursive_json_loads(requests.post(url = _url, data = data, files = files).content)
        # 判断是否为登陆状态
        try:
            if _obj.data.keepLogin == 'off' and _obj.data.title == 'Login':
                if not ZenTaoConfig.IS_USE_ZENTAO:
                    return None
                else:
                    log.info('app.modules.common.zentao.ZenTao#_doPost. zentao login timeout. do login again.')
                    self._doZenTaoLogin()
                    _url = self._getUrl(url)
                    _obj = recursive_json_loads(requests.post(url = _url, data = data, files = files).content)
        except:
            pass
        return _obj

    def doPost(self, url, data = None, files = None):
        if "" == self._sessionID:
            log.error("zentao sessionID is null . url=%s" % url)
            return None
        else:
            _obj = self._doPost(url, data = data, files = files)
        return _obj

    """
    公司信息
    """

    def CompanyInfo(self):
        _obj = self.doPost(ZenTaoConfig.ZENTAO_COMPANY_VIEW_URL)
        if _obj is not None and _obj.status == 'success':
            log.info("app.modules.common.zentao.ZenTao#CompanyInfo %s " % _obj.data.company)
            return _obj.data.company
        else:
            log.error("app.modules.common.zentao.ZenTao#CompanyInfo . obj is %s " % _obj)
            return None

    """
    禅道用户列表
    """

    def UserList(self):
        _obj = self.doPost(ZenTaoConfig.ZENTAO_COMPANY_BROWSE_URL)
        if _obj is not None and _obj.status == 'success':
            log.info("app.modules.common.zentao.ZenTao#UserList len=%s " % len(_obj.data.users))
            return _obj.data.users
        else:
            log.error("app.modules.common.zentao.ZenTao#UserList . obj is %s " % _obj)
            return None

    """
    项目列表
    """

    def ProjectList(self):
        _obj = self.doPost(ZenTaoConfig.ZENTAO_PROJECT_LIST_URL)
        if _obj is not None and _obj.status == 'success':
            log.info("app.modules.common.zentao.ZenTao#ProjectList len=%s " % len(_obj.data.projects))
            return _obj.data.projects
        else:
            log.error("app.modules.common.zentao.ZenTao#ProjectList . obj is %s " % _obj)
            return None

    """
    项目成员
    """

    def ProjectTeam(self, projectId):
        _url = '%s&projectID=%s' % (ZenTaoConfig.ZENTAO_PROJECT_TEAM_URL, projectId)
        _obj = self.doPost(_url)
        if _obj is not None and _obj.status == 'success':
            log.info("app.modules.common.zentao.ZenTao#ProjectTeam len=%s " % len(_obj.data.teamMembers))
            _teamMembers = _obj.data.teamMembers
            _members = []
            for _mem in _teamMembers:
                _members.append(_teamMembers[_mem])
            return _members
        else:
            log.error("app.modules.common.zentao.ZenTao#ProjectTeam . obj is %s " % _obj)
            return None

    """
    项目信息
    """

    def ProjectView(self, projectId):
        _url = '%s&projectID=%s' % (ZenTaoConfig.ZENTAO_PROJECT_VIEW_URL, projectId)
        _obj = self.doPost(_url)
        try:
            if _obj is not None and _obj.status == 'success':
                log.info("app.modules.common.zentao.ZenTao#ProjectView len=%s " % _obj.data)
                return _obj.data.project
            else:
                log.error("app.modules.common.zentao.ZenTao#ProjectView . obj is %s " % _obj)
                return None
        except BaseException as e:
            log.error("app.modules.common.zentao.ZenTao#ProjectView . obj is %s . %s" % (_obj, e.message))
            return None

    def ProjectProduct(self, projectId):
        """
        项目关联产品列表
        :param projectId:
        :return:
        """
        try:
            _url = '%s&projectID=%s' % (ZenTaoConfig.ZENTAO_PROJECT_PRODUCT_LIST_URL, projectId)
            _obj = self.doPost(_url)
            if _obj is not None and _obj.status == 'success':
                log.info("app.modules.common.zentao.ZenTao#ProjectProduct product=%s " % _obj.data.linkedProducts)
                if len(str(_obj.data.linkedProducts).strip()) == 0:
                    return None
                return _obj.data.linkedProducts
            else:
                log.error("app.modules.common.zentao.ZenTao#ProjectProduct . obj is %s " % _obj)
                return None
        except BaseException:
            log.error(traceback.format_exc())
        return None

    def ProductList(self):
        """
        产品列表
        :return:
        """
        _obj = self.doPost(ZenTaoConfig.ZENTAO_PRODUCT_LIST_URL)
        if _obj is not None and _obj.status == 'success':
            log.info("app.modules.common.zentao.ZenTao#ProductList len=%s " % len(_obj.data.products))
            return _obj.data.products
        else:
            log.error("app.modules.common.zentao.ZenTao#ProductList . obj is %s " % _obj)
            return None
        pass

    def AddBuild(self, projectId, _files):
        """
        为项目添加版本
        :param projectId:
        :param _files:
        :return:
        """
        try:
            _url = '%s&project=%s' % (ZenTaoConfig.ZENTAO_PROJECT_ADD_BUILD_URL, projectId)
            _obj = self.doPost(_url, files = _files)
            try:
                if _obj is not None and str(_obj).__contains__('buildID'):
                    log.info("app.modules.common.zentao.ZenTao#AddBuild len=%s " % _obj)
                    _buildId = re.sub("(.*)(buildID=)([0-9]+)(.*)(\\n*)(.*)(\\n*)", "\\3", _obj)
                    return _buildId
                else:
                    log.error("app.modules.common.zentao.ZenTao#AddBuild . obj is %s " % _obj)
                    return None
            except BaseException as e:
                log.error("app.modules.common.zentao.ZenTao#AddBuild . obj is %s . %s" % (_obj, e.message))
                return None
        except BaseException as e:
            log.error("app.modules.common.zentao.ZenTao#AddBuild 异常 . %s" % e.message)
        return None

    def AddTestTask(self, projectId, buildId, _data):
        """
        版本提交测试
        :param projectId:
        :param buildId:
        :param _data:
        :return:
        """
        _url = '%s&project=%s&build=%s' % (ZenTaoConfig.ZENTAO_CREATE_TEST_TASK_URL, projectId, buildId)
        _obj = self.doPost(_url, data = _data)
        log.info("app.modules.common.zentao.ZenTao#AddTestTask _obj=%s " % _obj)
        return _obj

    def CreatePlan(self, _data):
        """
        创建项目
        :return:
        """
        if BaseConfig.OPERATE_ZENTAO:
            _obj = self.doPost(ZenTaoConfig.ZENTAO_CREATE_PLAN_URL, data = _data)
        else:
            _obj = "aaa&projectID=00"
        log.info("app.modules.common.zentao.ZenTao#CreatePlan _obj=%s " % _obj)
        return _obj

    def UpdatePlanMembers(self, projectId, _data):
        """
        修改项目成员
        :return:
        """
        if BaseConfig.OPERATE_ZENTAO:
            _url = '%s&projectID=%s' % (ZenTaoConfig.ZENTAO_UPDATE_PLAN_MEMBERS_URL, projectId)
            _obj = self.doPost(_url, data = _data)
        else:
            _obj = None
        log.info("app.modules.common.zentao.ZenTao#UpdatePlanMembers _obj=%s " % _obj)
        return _obj

    def DeletePlanMembers(self, projectId, account):
        """
        删除项目成员
        :return:
        """
        if BaseConfig.OPERATE_ZENTAO:
            _url = '%s&projectID=%s&account=%s&confirm=yes&t=json' % (
                ZenTaoConfig.ZENTAO_DELETE_PLAN_MEMBERS_URL, projectId, account)
            _obj = self.doPost(_url)
        else:
            _obj = None
        log.info("app.modules.common.zentao.ZenTao#DeletePlanMembers _obj=%s " % _obj)
        return _obj

    def UpdatePlanInfo(self, projectId, _data):
        """
        更新项目信息
        name:matrix-测试
        code:
        begin:2018-01-02
        end:2018-03-16
        days:34
        type:sprint
        classify:business
        team:12
        status:wait
        PO:
        QD:
        PM:beetle
        RD:
        products[]:43
        desc:这是一个测试用的例子<br />
        acl:open

        :param projectId:
        :param _data:
        :return:
        """
        if BaseConfig.OPERATE_ZENTAO:
            _url = '%s&project=%s' % (ZenTaoConfig.ZENTAO_UPDATE_PLAN_URL, projectId)
            _obj = self.doPost(_url, data = _data)
        else:
            _obj = None
        log.info("app.modules.common.zentao.ZenTao#UpdatePlanInfo _obj=%s " % _obj)
        return _obj

    def test(self):
        _files = {'product': (None, '37'), 'name': (None, 'test15'), 'builder': (None, 'admin'),
                  'date': (None, '2017-09-07')}
        _buildId = self.AddBuild(1559, _files)

        _json = {'product': '37', 'project': 1559, 'build': _buildId, 'owner': 'admin', 'pri': '0',
                 'begin': '2017-09-06', 'end': '2017-09-06', 'status': 'wait', 'name': 'cccccc'}
        _obj = self.AddTestTask(1559, _buildId, _json)

        # return _obj.data.projects
        # return self.ProjectView('1204')
        # return self.CompanyInfo()
